#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>

//#define VERBOSE
//#define USEDP

using namespace std;

typedef struct _TNode {
	int adjSize;
	int adj[110];
	int idx;
} TNode;

bool operator < (const TNode& x, const TNode& y) {
	return x.adjSize < y.adjSize;
}

int n, m;
TNode nodes[110];
TNode bakNodes[110];

bool addIn[110];
bool everVisit[110];
bool visit[110];
bool hasEdge[110][110];
int color[110];
int avaliable;

int curB;
int maxB;
int maxColor[110];

int searched = 0;
int idxMapping[110];

int searchlist[110];
int searchLen;
const int MAXDP = 20;
bool quit = false;

int countMess(int x) {
	if (visit[x]) return 0;
	visit[x] = true;
	int res = 0;
	for (int i=0; i<nodes[x].adjSize; ++i)
		if (color[nodes[x].adj[i]] == 0)
			res += countMess(idxMapping[nodes[x].adj[i]]);
	return res+1;
}

bool visitForTot[110];

int cntLeftNodes(int x) {
	visitForTot[x] = true;
	everVisit[x] = true;
	int sum = 1;
	for (int i=0; i<nodes[x].adjSize; ++i) {
		int son = nodes[x].adj[i];
		if (visitForTot[son] || visit[son]) continue;
		sum += cntLeftNodes(son);
	}
	return sum;
}

#ifdef USEDP

int rec[1<<MAXDP];
int path[1<<MAXDP];
int updateTime[1<<MAXDP];
int theTime = 0;
int states[MAXDP];
int statesLen = 0;
int adjMat[MAXDP];

int searchDPInternal(int s) {
	if (updateTime[s] == theTime) return rec[s];
	searched++;
	int maxV = 0;
	int maxI = -1;

	int i=s;
	int idx = statesLen-1;
	while (i>0) {
		int r=i%2;
		i = i>>1;
		if (r == 1) {
			int val = searchDPInternal(s&adjMat[idx]) + 1;
			if (val > maxV) {
				maxV = val;
				maxI = idx;
			}
		}
		--idx;
	}

	updateTime[s] = theTime;
	rec[s] = maxV;
	path[s] = maxI;
	return rec[s];
}

int searchDP(void) {
	++theTime;
	statesLen = 0;
	for (int i=0; i<n; ++i) {
		if (visitForTot[i]) {
			everVisit[i] = true;
			adjMat[statesLen] = 0;
			for (int j=0; j<n; ++j) {
				if (visitForTot[j]) {
					if (i==j || hasEdge[i][j])
						adjMat[statesLen] = (adjMat[statesLen]<<1) + 0;
					else
						adjMat[statesLen] = (adjMat[statesLen]<<1) + 1;
				}
			}
			states[statesLen++] = i;
		}
	}
	return searchDPInternal((1<<statesLen)-1);
}

void setColor(void) {
	for (int i=0; i<statesLen; ++i) 
		color[states[i]] = 'w';
	int s=(1<<statesLen)-1;
	while (path[s] != -1) {
		color[states[path[s]]] = 'b';
		s = s&adjMat[path[s]];
	}
}

#endif

int solNum = 0;
int MAXQUIT = 10;

void search(int searchIdx) {
	++searched;
	if (quit) return;
	if (searchIdx>=n) {
		int b = 0;
		for (int i=0; i<n; ++i)
			if (color[i] == 'b') ++b;
		++solNum;
		if (solNum==MAXQUIT) quit = true;
		if (b > maxB) {
			maxB = b;
			memcpy(maxColor, color, sizeof(int)*n);

#ifdef VERBOSE
			cout << "current max B: " << maxB << endl;
			bool firstBlood = true;
			for (int i=0; i<n; ++i)
				if (maxColor[i] == 'b') {
					if (firstBlood) {
						cout << (i+1);
						firstBlood = false;
					} else
						cout << " " << (i+1);
				}
			cout << endl;
#endif
		}

		return;
	}

	int x = searchlist[searchIdx];
	if (visit[x]) {
		search(searchIdx+1);
		return;
	}
	{
		int b = 0;
		for (int i=0; i<n; ++i)
			if (visit[i] && color[i] == 'b') ++b;
		curB = b;
	}



	everVisit[x] = true;
	
#ifdef USEDP
 	memset(visitForTot, 0, n);
 	int tot = cntLeftNodes(x);
#endif

	int unvisit = 0;
	for (int i=0; i<n; ++i)
		if (!visit[i]) ++unvisit;

	bool hasB = false;
	for (int i=0; i<nodes[x].adjSize; ++i) {
		if (visit[nodes[x].adj[i]] && color[nodes[x].adj[i]]=='b') {
			hasB = true;
			break;
		}
	}

	visit[x] = true;
	if (hasB) --unvisit;

	if (unvisit + curB <= maxB) {
// 		cout << "prunched:" << searchIdx << " " << unvisit << " "
// 			<< curB << " " << maxB << endl;
		visit[x] = false;
		return;
	}

	int setList[110];
	int setIdx = 0;

#ifdef USEDP
	if (tot <= MAXDP) {
		searchDP();
		setColor();
		visit[x] = false;
		memcpy(setList, states, sizeof(int)*statesLen);
		setIdx = statesLen;
		for (int i=0; i<setIdx; ++i)
			visit[setList[i]] = true;
		search(searchIdx+1);
		for (int i=0; i<setIdx; ++i)
			visit[setList[i]] = false;
		return;
	}
#endif

	if (!hasB) {
// 		cout << searchIdx << " " << unvisit << " "
// 			<< curB << " " << maxB << endl;
		color[x] = 'b';
		for (int i=0; i<nodes[x].adjSize; ++i)
			if (visit[nodes[x].adj[i]]) continue;
			else {
				color[nodes[x].adj[i]] = 'w';
				everVisit[nodes[x].adj[i]] = true;
				visit[nodes[x].adj[i]] = true;
				setList[setIdx++] = nodes[x].adj[i];
			}
		search(searchIdx+1);
		for (int i=0; i<setIdx; ++i) {
			visit[setList[i]] = false;
		}
	}
	color[x] = 'w';
	search(searchIdx+1);
	visit[x] = false;
}


int main(void)
{
	int totTestcase;
	cin >> totTestcase;
	for (int testcase = 0; testcase < totTestcase; ++testcase) {
		cin >> n >> m;
		for (int i=0; i<110; ++i) {
			nodes[i].adjSize = 0;
			nodes[i].idx = i;
		}
		memset(hasEdge, 0, 110*110);
		for (int i=0; i<m; ++i) {
			int a, b;
			cin >> a >> b;
			--a;--b;
			if (hasEdge[a][b]) continue;
			nodes[a].adj[nodes[a].adjSize++] = b;
			nodes[b].adj[nodes[b].adjSize++] = a;
			hasEdge[a][b] = hasEdge[b][a] = true;
		}

		memcpy(bakNodes, nodes, sizeof(TNode)*n);
		sort(nodes, nodes+n);
		for (int i=0; i<n; ++i)
			searchlist[i] = nodes[i].idx;
		memcpy(nodes, bakNodes, sizeof(TNode)*n);

#ifdef VERBOSE
		cout << "order: " << endl;
		for (int i=0; i<n; ++i)
			cout << searchlist[i]+1 << " ";
		cout << endl;
		cout << "adjSize: " << endl;
		for (int i=0; i<n; ++i)
			cout << nodes[searchlist[i]].adjSize << " ";
		cout << endl;
#endif

		maxB = 0;
		MAXQUIT = 10;
		searched = 0;
		memset(everVisit, 0, 110);
		for (int i=0; i<n; ++i) {
			if (!everVisit[searchlist[i]]) {
				memset(visit, 0, 110);
				search(i);
			}
		}

		memcpy(bakNodes, nodes, sizeof(TNode)*n);
		sort(nodes, nodes+n);
		reverse(nodes, nodes+n);
		for (int i=0; i<n; ++i)
			searchlist[i] = nodes[i].idx;
		memcpy(nodes, bakNodes, sizeof(TNode)*n);

		MAXQUIT = -1;
		quit = false;
		memset(everVisit, 0, 110);
		for (int i=0; i<n; ++i) {
			if (!everVisit[searchlist[i]]) {
				memset(visit, 0, 110);
				search(i);
			}
		}

		if (testcase>0) cout << endl;
// 		cout << "searched node: " << searched << endl;
		maxB = 0;
		for (int i=0; i<n; ++i)
			if (maxColor[i] == 'b') ++maxB;
		cout << maxB << endl;
		bool firstBlood = true;
		for (int i=0; i<n; ++i)
			if (maxColor[i] == 'b') {
				if (firstBlood) {
					cout << (i+1);
					firstBlood = false;
				} else
					cout << " " << (i+1);
			}
	}
	cout << endl;
	return 0;
}